import 'index.dart';

/// 高级ZVT服务类
/// 提供更高级的支付功能和业务逻辑
class ZVTService {
  static ZVTService? _instance;
  ZVTService._();

  static ZVTService get instance => _instance ??= ZVTService._();

  final ZVTPayment _zvtPayment = ZVTPayment.current();

  /// 初始化服务
  /// [ip] 终端IP地址
  /// [port] 终端端口，默认20008
  /// [connectionTimeout] 连接超时时间
  /// [operationTimeout] 操作超时时间
  void initialize({
    required String ip,
    int port = 20008,
    Duration? connectionTimeout,
    Duration? operationTimeout,
  }) {
    _zvtPayment.setConnectIP(ip: ip, port: port);

    if (connectionTimeout != null) {
      _zvtPayment.setConnectionTimeout(connectionTimeout);
    }

    if (operationTimeout != null) {
      _zvtPayment.setOperationTimeout(operationTimeout);
    }
  }

  /// 销售交易
  /// [amount] 交易金额
  /// [currency] 货币类型，默认EUR
  /// [paymentType] 支付类型，默认PTS_EXCLUDING_GELDKARTE
  /// [transactionId] 交易ID，如果不提供会自动生成
  /// [timeout] 超时时间（秒）
  /// [maxStatusInfos] 最大状态信息数量
  /// [codeLog] 日志回调函数
  Future<TransactionResponse> sale({
    required double amount,
    String? transactionId,
    int? timeout,
    int? maxStatusInfos,
    Function(String)? codeLog,
  }) async {
    // 验证参数
    final errors = ZVTPayment.validateTransactionParams(
      amount: amount,
      transactionId: transactionId,
      timeout: timeout,
      maxStatusInfos: maxStatusInfos,
    );

    if (errors.isNotEmpty) {
      throw ZVTException('参数验证失败: ${errors.values.join(', ')}');
    }

    try {
      final result = await _zvtPayment.authorization(
        amount: amount,
        timeout: timeout,
        maxStatusInfos: maxStatusInfos,
        codeLog: codeLog,
      );

      return result;
    } catch (e) {
      rethrow;
    }
  }

  /// 关闭批次（日终结算）
  /// [codeLog] 日志回调函数
  Future<TransactionResponse> endOfDay({
    Function(String)? codeLog,
  }) async {
    try {
      final result = await _zvtPayment.endOfDay(codeLog: codeLog);

      return result;
    } catch (e) {
      rethrow;
    }
  }

  /// 中止交易
  /// [codeLog] 日志回调函数
  Future<TransactionResponse> abort({
    Function(String)? codeLog,
  }) async {
    try {
      final result = await _zvtPayment.abort(codeLog: codeLog);

      return result;
    } catch (e) {
      rethrow;
    }
  }

  /// 冲正交易
  /// [batchNumber] 原始交易ID
  /// [codeLog] 日志回调函数
  Future<TransactionResponse> reversal({
    required String batchNumber,
    Function(String)? codeLog,
  }) async {
    try {
      final result = await _zvtPayment.reversal(
        batchNumber: batchNumber,
        codeLog: codeLog,
      );

      return result;
    } catch (e) {
      rethrow;
    }
  }

  /// 批量销售交易
  /// [transactions] 交易列表
  /// [onProgress] 进度回调
  /// [codeLog] 日志回调函数
  Future<List<TransactionResponse>> batchSale({
    required List<TransactionParams> transactions,
    Function(int current, int total, TransactionResponse result)? onProgress,
    Function(String)? codeLog,
  }) async {
    return await _zvtPayment.batchProcess(
      transactions: transactions,
      onProgress: onProgress,
    );
  }

  /// 获取连接状态
  bool get isConnected => _zvtPayment.isConnected;

  /// 获取连接信息
  Map<String, dynamic> getConnectionInfo() => _zvtPayment.getConnectionInfo();

  /// 获取交易统计信息
  Map<String, dynamic> getTransactionStats() =>
      _zvtPayment.getTransactionStats();

  /// 重置统计信息
  void resetStats() => _zvtPayment.resetStats();

  /// 获取最后错误信息
  String? get lastError => _zvtPayment.lastError;

  /// 清除错误信息
  void clearError() => _zvtPayment.clearError();

  /// 断开连接
  void disconnect() => _zvtPayment.disconnect();

  /// 检查终端状态
  Future<Map<String, dynamic>> checkTerminalStatus({
    Function(String)? codeLog,
  }) async {
    try {
      // 尝试中止交易来检查终端状态
      final result = await abort(codeLog: codeLog);

      return {
        'status': 'online',
        'message': '终端在线且响应正常',
        'timestamp': DateTime.now().toIso8601String(),
        'details': result,
      };
    } on ZVTException catch (e) {
      return {
        'status': 'error',
        'message': e.message,
        'timestamp': DateTime.now().toIso8601String(),
        'errorCode': e.resultCode,
        'details': e.details,
      };
    } catch (e) {
      return {
        'status': 'offline',
        'message': '终端离线或无法连接',
        'timestamp': DateTime.now().toIso8601String(),
        'error': e.toString(),
      };
    }
  }

  /// 获取状态码描述
  static String getStatusCodeDescription(int statusCode) {
    return ZVTUtils.getStatusCodeDescription(statusCode);
  }
}
